/*
 * lista.h
 *
 *  Created on: 24/03/2013
 *      Author: dario
 */

#ifndef LISTA_H_
#define LISTA_H_
#define ERROR_LISTA_VACIA -1
#define RES_OK 0

#include "nodo.h"

/*La lista esta formada por una sucesion de nodos, se guarda un puntero al primero
 *y al ultimo, a partir del primer nodo se puede recorrer la lista.
 *El atributo actual es de uso interno de la lista, para guardar el progreso de
 *un recorrido.
 */
typedef struct Lista Lista;
struct Lista {
	unsigned int length;
	Nodo* primero;
	Nodo* ultimo;
	Nodo* actual;
	/*Destructor del dato que almacena, puede ser NULL*/
	void (*DestructorDelDato)(void* a);
};

/*Al construir la lista necesito conocer el destructor del dato que va a almacenar
 *o puede ser NULL si no es necesario destruirlo.
 */
Lista* ConstruirLista(void (*Funcion)(void* a));

/*Destructor de la lista*/
void DestruirLista(Lista* list);

/*Devuelve 1 si la lista esta vacia, 0 si tiene elementos*/
int ListaVacia(Lista* list);

/*Devuelve la longitud de la lista luego de agregar el emento*/
int AgregarElemento(Lista* list, void* elemento);

/*Devuelve la cantidad de elemnentos en la lista*/
int GetLongitud(Lista* list);

/*Se posiciona al principio de la lista para empezar a recorrer. Devuelve
 *un codigo de error si la lista esta vacia.*/
int IniciarRecorrido(Lista* list);

/*Obtiene el elemento donde se esta posicioado el recorrido y luego avanza*/
void* GetElementoActual(Lista* list);

/*Determina si un elemento forma parte de la lista, para ello compara cada elemento
 *de la lista, con el pasado por parametro, haciendo uso de la funcion Comparadora
 *Devuelve un puntero al elemento si existe, si no NULL.
 */
void* ExisteElemento(Lista* list, void* elemento,
		int (*Comparadora)(void* a, void* b));

/*Obtiene el primer elemento de la lista, NULL si la lista esta vacia*/
void* GetPrimerElemento(Lista* list);

/*Funcion generica para pasar como puntero a funcion a contenedores que vayan a almacenar
 * listas, para que puedan destruirlas.
 */
void DestructuraDeListas(void* l);

/*Funcion generica para pasar como puntero a funcion y poder imprimir listas
 *El parametro pfuncion servira para imprimir los elementos de la lista.*/
void ImprimirLista(Lista* l, void (*pfuncion)(void* a));

/*Devuelve el indice, a partir de 0, donde se encuentra el elemento en la lista
 *-1 si el elemento no existe. Compara usando la funcion comparadora.
 */
int DevolverIndiceElemento(Lista* list, void* elemento,
		int (*Comparadora)(void* a, void* b));

/*Accede a un elemento de la lista, mediante el indice ingresado*/
void* GetElementoXIndice(Lista* list, int indice);

#endif /* LISTA_H_ */
